home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xmris / create.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  36.2 KB  |  1,115 lines

  1. /*{{{  (C) 1992 Nathan Sidwell*/
  2. /*****************************************************************************
  3.             X M R I S V1.01
  4.             ---------------
  5.             (C) 1992 Nathan Sidwell
  6.  
  7. This program is copyright (C) 1992 Nathan Sidwell. This software and documentation
  8. is in the public domain. Permission is granted to distribute and compile
  9. verbatim copies of this software for non-commercial, non-profit use,
  10. without fee. The software may be modified, provided that both the above copyright
  11. notice and this permission notice appear.
  12.  
  13. No guarantee is given as to the robustness or suitability of this
  14. software for your computer.
  15.  
  16. Nathan Sidwell  INMOS UK |                 | nathan@inmos.co.uk       DoD#0390
  17. *****************************************************************************/
  18. /*}}}*/
  19. #define EXTERN
  20. #include "xmris.h"
  21. /*{{{  bitmaps*/
  22. /*{{{  bitmaps/icon/.*/
  23. #include "bitmaps/icon/mris.h"
  24. #include "bitmaps/icon/msit.h"
  25. #include "bitmaps/icon/cursor.h"
  26. #include "bitmaps/icon/cursorm.h"
  27. #include "bitmaps/icon/solidm.h"
  28. #include "bitmaps/icon/solidr.h"
  29. #include "bitmaps/icon/solidi.h"
  30. #include "bitmaps/icon/solids.h"
  31. #include "bitmaps/icon/solidt.h"
  32. #include "bitmaps/icon/shellm.h"
  33. #include "bitmaps/icon/shellr.h"
  34. #include "bitmaps/icon/shelli.h"
  35. #include "bitmaps/icon/shells.h"
  36. #include "bitmaps/icon/shellt.h"
  37. #include "bitmaps/icon/bigm.h"
  38. #include "bitmaps/icon/bigr.h"
  39. #include "bitmaps/icon/bigi.h"
  40. #include "bitmaps/icon/bigs.h"
  41. #include "bitmaps/icon/bigt.h"
  42. /*}}}*/
  43. /*{{{  bitmaps/board/.*/
  44. #include "bitmaps/board/oblong.h"
  45. #include "bitmaps/board/rect.h"
  46. #include "bitmaps/board/munchtb.h"
  47. #include "bitmaps/board/munchlr.h"
  48. #include "bitmaps/board/edgetb.h"
  49. #include "bitmaps/board/edgelr.h"
  50. #include "bitmaps/board/fill0.h"
  51. #include "bitmaps/board/fill1.h"
  52. #include "bitmaps/board/fill2.h"
  53. #include "bitmaps/board/fill3.h"
  54. #include "bitmaps/board/digits.h"
  55. #include "bitmaps/board/digitsm.h"
  56. #include "bitmaps/board/cherry.h"
  57. #include "bitmaps/board/cherrym.h"
  58. /*}}}*/
  59. /*{{{  bitmaps/apple/.*/
  60. #include "bitmaps/apple/apple.h"
  61. #include "bitmaps/apple/applem.h"
  62. #include "bitmaps/apple/rock.h"
  63. #include "bitmaps/apple/rockm.h"
  64. #include "bitmaps/apple/split.h"
  65. #include "bitmaps/apple/splitm.h"
  66. #include "bitmaps/apple/decay.h"
  67. #include "bitmaps/apple/decaym.h"
  68. #include "bitmaps/apple/rot.h"
  69. #include "bitmaps/apple/rotm.h"
  70. /*}}}*/
  71. /*{{{  bitmaps/player/.*/
  72. #include "bitmaps/player/ball.h"
  73. #include "bitmaps/player/plyrrt1.h"
  74. #include "bitmaps/player/plyrrt1m.h"
  75. #include "bitmaps/player/plyrrt2.h"
  76. #include "bitmaps/player/plyrrt2m.h"
  77. #include "bitmaps/player/plyrup1.h"
  78. #include "bitmaps/player/plyrup1m.h"
  79. #include "bitmaps/player/plyrup2.h"
  80. #include "bitmaps/player/plyrup2m.h"
  81. #include "bitmaps/player/plyrps1.h"
  82. #include "bitmaps/player/plyrps1m.h"
  83. #include "bitmaps/player/plyrps2.h"
  84. #include "bitmaps/player/plyrps2m.h"
  85. #include "bitmaps/player/plyrsq.h"
  86. #include "bitmaps/player/plyrsqm.h"
  87. /*}}}*/
  88. /*{{{  bitmaps/normal/.*/
  89. #include "bitmaps/normal/normrt1.h"
  90. #include "bitmaps/normal/normrt1m.h"
  91. #include "bitmaps/normal/normrt2.h"
  92. #include "bitmaps/normal/normrt2m.h"
  93. #include "bitmaps/normal/normup1.h"
  94. #include "bitmaps/normal/normup1m.h"
  95. #include "bitmaps/normal/normup2.h"
  96. #include "bitmaps/normal/normup2m.h"
  97. #include "bitmaps/normal/normsq.h"
  98. #include "bitmaps/normal/normsqm.h"
  99. #include "bitmaps/normal/den.h"
  100. #include "bitmaps/normal/denm.h"
  101. /*}}}*/
  102. /*{{{  bitmaps/munch/.*/
  103. #include "bitmaps/munch/mnchrt1.h"
  104. #include "bitmaps/munch/mnchrt1m.h"
  105. #include "bitmaps/munch/mnchrt2.h"
  106. #include "bitmaps/munch/mnchrt2m.h"
  107. #include "bitmaps/munch/mnchup1.h"
  108. #include "bitmaps/munch/mnchup1m.h"
  109. #include "bitmaps/munch/mnchup2.h"
  110. #include "bitmaps/munch/mnchup2m.h"
  111. #include "bitmaps/munch/mnchsq.h"
  112. #include "bitmaps/munch/mnchsqm.h"
  113. /*}}}*/
  114. /*{{{  bitmaps/xtra/.*/
  115. #include "bitmaps/xtra/xtra1.h"
  116. #include "bitmaps/xtra/xtra1m.h"
  117. #include "bitmaps/xtra/xtra2.h"
  118. #include "bitmaps/xtra/xtra2m.h"
  119. #include "bitmaps/xtra/xtrasq.h"
  120. #include "bitmaps/xtra/xtrasqm.h"
  121. #include "bitmaps/xtra/xtrbold.h"
  122. #include "bitmaps/xtra/xtrfaint.h"
  123. /*}}}*/
  124. /*{{{  bitmaps/drone/.*/
  125. #include "bitmaps/drone/dronrt1.h"
  126. #include "bitmaps/drone/dronrt1m.h"
  127. #include "bitmaps/drone/dronrt2.h"
  128. #include "bitmaps/drone/dronrt2m.h"
  129. #include "bitmaps/drone/dronup1.h"
  130. #include "bitmaps/drone/dronup1m.h"
  131. #include "bitmaps/drone/dronup2.h"
  132. #include "bitmaps/drone/dronup2m.h"
  133. #include "bitmaps/drone/dronsq.h"
  134. #include "bitmaps/drone/dronsqm.h"
  135. /*}}}*/
  136. /*{{{  bitmaps/chomp/.*/
  137. #include "bitmaps/chomp/chmpopn.h"
  138. #include "bitmaps/chomp/chmpopnm.h"
  139. #include "bitmaps/chomp/chmpcls.h"
  140. #include "bitmaps/chomp/chmpclsm.h"
  141. /*}}}*/
  142. /*{{{  bitmaps/prize/.*/
  143. #include "bitmaps/prize/cake.h"
  144. #include "bitmaps/prize/cakem.h"
  145. #include "bitmaps/prize/spanner.h"
  146. #include "bitmaps/prize/spannerm.h"
  147. #include "bitmaps/prize/brolly.h"
  148. #include "bitmaps/prize/brollym.h"
  149. #include "bitmaps/prize/mushrm.h"
  150. #include "bitmaps/prize/mushrmm.h"
  151. #include "bitmaps/prize/clock.h"
  152. #include "bitmaps/prize/clockm.h"
  153. /*}}}*/
  154. /*}}}*/
  155. #define XTRA_LETTER_X   ((xtra1_x_hot + xtra2_x_hot) >> 1)
  156. #define XTRA_LETTER_Y   ((xtra1_y_hot + xtra2_y_hot) >> 1)
  157. static unsigned long const colour_zero = 0;
  158. static unsigned long const colour_one = ~0;
  159. /*{{{  typedef struct Context*/
  160. typedef struct Context
  161. /* GC definer */
  162. {
  163.   int       function;         /* graphics function */
  164.   unsigned long const *fgp;   /* foreground colour pointer */
  165.   unsigned long const *bgp;   /* background colour pointer */
  166. } CONTEXT;
  167. /*}}}*/
  168. /*{{{  gcsdefine*/
  169. static CONTEXT gcsdefine[GCS] =
  170. {
  171.     {GXcopy,        &colour_one,    &colour_zero},
  172.     {GXcopy,        &display.white, &colour_zero},
  173.     {GXcopy,        &display.black, &colour_zero},
  174.     {GXandInverted, &colour_one,    &colour_zero},
  175.     {GXor,          &colour_one,    &colour_zero},
  176.     {GXor,          &display.white, &colour_zero},
  177.     {GXxor,         &display.xor,   &colour_zero},
  178.     {GXcopy,        &display.black, &display.white},
  179.     {GXand,         &colour_one,    &colour_zero},
  180.     {GXcopy,        &display.black, &display.white},
  181. };
  182. /*}}}*/
  183. /*{{{  tables*/
  184. /*{{{  ARG const args[] =*/
  185. ARG const args[] =
  186. {
  187.   {"help",    1, &flags.help,     "This help"},
  188.   {"display",-1, &display.name,   "Display to run on"},
  189.   {"font",   -1, &font.name,      "Font name"},
  190.   {"rv",      1, &flags.reverse,  "Reverse video"},
  191.   {"bw",      1, &flags.bw,       "Force black and white"},
  192.   {"iconic",  1, &flags.iconic,   "Start iconic"},
  193.   {"mris",    0, &flags.gender,   "Male version"},
  194.   {"msit",    1, &flags.gender,   "Female version"},
  195.   {NULL}
  196. };
  197. /*}}}*/
  198. /*{{{  SPRITE sprites[] =*/
  199. SPRITE sprites[] =
  200. {
  201.   /*{{{  2:center masks (oblong, rect)*/
  202.   {NULL, oblong_bits, oblong_width, oblong_height, {CELL_WIDTH, CELL_HEIGHT}},
  203.   {NULL, rect_bits, rect_width, rect_height, {CELL_WIDTH, CELL_HEIGHT}},
  204.   /*}}}*/
  205.   /*{{{  2:munch masks (tb,lr)*/
  206.   {NULL, munchtb_bits, munchtb_width, munchtb_height, {CELL_WIDTH, MUNCH_HEIGHT}},
  207.   {NULL, munchlr_bits, munchlr_width, munchlr_height, {MUNCH_WIDTH, CELL_HEIGHT}},
  208.   /*}}}*/
  209.   /*{{{  2:edge masks (tb, lr)*/
  210.   {NULL, edgetb_bits, edgetb_width, edgetb_height, {GAP_WIDTH * 5, EDGE_HEIGHT}},
  211.   {NULL, edgelr_bits, edgelr_width, edgelr_height, {EDGE_WIDTH, GAP_HEIGHT * 5}},
  212.   /*}}}*/
  213.   /*{{{  4:fills (0,1,2,3)*/
  214.   {fill0_bits, NULL, fill0_width, fill0_height, {0, 0}},
  215.   {fill1_bits, NULL, fill1_width, fill1_height, {0, 0}},
  216.   {fill2_bits, NULL, fill2_width, fill2_height, {0, 0}},
  217.   {fill3_bits, NULL, fill3_width, fill3_height, {0, 0}},
  218.   /*}}}*/
  219.   /*{{{  1:digits (0,1,2,3,4,5,6,7,8,9,' ')*/
  220.   {digits_bits, digitsm_bits, digits_width, digits_height, {DIGIT_WIDTH * 11, DIGIT_HEIGHT}},
  221.   /*}}}*/
  222.   /*{{{  1:cherry*/
  223.   {cherry_bits, cherrym_bits, cherry_width, cherry_height, {CELL_WIDTH, CELL_HEIGHT}},
  224.   /*}}}*/
  225.   /*{{{  1:den*/
  226.   {den_bits, denm_bits, den_width, den_height, {CELL_WIDTH, CELL_HEIGHT}},
  227.   /*}}}*/
  228.   /*{{{  1:ball*/
  229.   {ball_bits, ball_bits, ball_width, ball_height, {BALL_WIDTH, BALL_HEIGHT}},
  230.   /*}}}*/
  231.   /*{{{  6:apples (apple, rock, apple, split, decay, rot)*/
  232.   {apple_bits, applem_bits, apple_width, apple_height, {CELL_WIDTH, CELL_HEIGHT}},
  233.   {rock_bits,  rockm_bits,  rock_width,  rock_height,  {CELL_WIDTH, CELL_HEIGHT}},
  234.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_APPLE, 0},
  235.   {split_bits, splitm_bits, split_width, split_height, {CELL_WIDTH, CELL_HEIGHT}},
  236.   {decay_bits, decaym_bits, decay_width, decay_height, {DECAY_WIDTH, DECAY_HEIGHT}},
  237.   {rot_bits,   rotm_bits,   rot_width,   rot_height, {ROT_WIDTH, ROT_HEIGHT}},
  238.   /*}}}*/
  239.   /*{{{  2:extra (bold, faint)*/
  240.   {xtrbold_bits,  xtrbold_bits, xtrbold_width,  xtrbold_height, {CELL_WIDTH / 2 * 5, CELL_HEIGHT / 2}},
  241.   {xtrfaint_bits, xtrbold_bits, xtrfaint_width, xtrfaint_height, {CELL_WIDTH / 2 * 5, CELL_HEIGHT / 2}},
  242.   /*}}}*/
  243.   /*{{{  2:xtra source*/
  244.   {xtra1_bits, xtra1m_bits, xtra1_width, xtra1_height, {CELL_WIDTH, CELL_HEIGHT}},
  245.   {xtra2_bits, xtra2m_bits, xtra2_width, xtra2_height, {CELL_WIDTH, CELL_HEIGHT}},
  246.   /*}}}*/
  247.   /*{{{  12:normal (ul, dr, l, r, ur, dl)*/
  248.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_NORMAL + 8, 1},
  249.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_NORMAL + 9, 1},
  250.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_NORMAL + 8, 2},
  251.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_NORMAL + 9, 2},
  252.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_NORMAL + 6, 1},
  253.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_NORMAL + 7, 1},
  254.   {normrt1_bits, normrt1m_bits, normrt1_width, normrt1_height, {CELL_WIDTH, CELL_HEIGHT}},
  255.   {normrt2_bits, normrt2m_bits, normrt2_width, normrt2_height, {CELL_WIDTH, CELL_HEIGHT}},
  256.   {normup1_bits, normup1m_bits, normup1_width, normup1_height, {CELL_WIDTH, CELL_HEIGHT}},
  257.   {normup2_bits, normup2m_bits, normup2_width, normup1_height, {CELL_WIDTH, CELL_HEIGHT}},
  258.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_NORMAL + 0, 2},
  259.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_NORMAL + 1, 2},
  260.   /*}}}*/
  261.   /*{{{  12:muncher (ul, dr, l, r, ur, dl)*/
  262.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_MUNCHER + 8, 1},
  263.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_MUNCHER + 9, 1},
  264.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_MUNCHER + 8, 2},
  265.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_MUNCHER + 9, 2},
  266.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_MUNCHER + 6, 1},
  267.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_MUNCHER + 7, 1},
  268.   {mnchrt1_bits, mnchrt1m_bits, mnchrt1_width, mnchrt1_height, {CELL_WIDTH, CELL_HEIGHT}},
  269.   {mnchrt2_bits, mnchrt2m_bits, mnchrt2_width, mnchrt2_height, {CELL_WIDTH, CELL_HEIGHT}},
  270.   {mnchup1_bits, mnchup1m_bits, mnchup1_width, mnchup1_height, {CELL_WIDTH, CELL_HEIGHT}},
  271.   {mnchup2_bits, mnchup2m_bits, mnchup2_width, mnchup2_height, {CELL_WIDTH, CELL_HEIGHT}},
  272.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_MUNCHER + 0, 2},
  273.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_MUNCHER + 1, 2},
  274.   /*}}}*/
  275.   /*{{{  12:xtra (ul, dr, l, r, ur, dl)*/
  276.   {xtra1_bits, xtra1m_bits, xtra1_width, xtra1_height, {CELL_WIDTH, CELL_HEIGHT}},
  277.   {xtra2_bits, xtra2m_bits, xtra2_width, xtra2_height, {CELL_WIDTH, CELL_HEIGHT}},
  278.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 0, 0},
  279.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 1, 0},
  280.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 0, 0},
  281.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 1, 0},
  282.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 0, 0},
  283.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 1, 0},
  284.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 0, 0},
  285.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 1, 0},
  286.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 0, 0},
  287.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_XTRA + 1, 0},
  288.   /*}}}*/
  289.   /*{{{  12:drone (ul, dr, l, r, ur, dl)*/
  290.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_DRONE + 8, 1},
  291.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_DRONE + 9, 1},
  292.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_DRONE + 8, 2},
  293.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_DRONE + 9, 2},
  294.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_DRONE + 6, 1},
  295.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_DRONE + 7, 1},
  296.   {dronrt1_bits, dronrt1m_bits, dronrt1_width, dronrt1_height, {CELL_WIDTH, CELL_HEIGHT}},
  297.   {dronrt2_bits, dronrt2m_bits, dronrt2_width, dronrt2_height, {CELL_WIDTH, CELL_HEIGHT}},
  298.   {dronup1_bits, dronup1m_bits, dronup1_width, dronup1_height, {CELL_WIDTH, CELL_HEIGHT}},
  299.   {dronup2_bits, dronup2m_bits, dronup2_width, dronup2_height, {CELL_WIDTH, CELL_HEIGHT}},
  300.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_DRONE + 0, 2},
  301.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_DRONE + 1, 2},
  302.   /*}}}*/
  303.   /*{{{  12:player (ul, dr, l, r, ur, dl)*/
  304.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 8, 1},
  305.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 9, 1},
  306.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 8, 2},
  307.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 9, 2},
  308.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 6, 1},
  309.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 7, 1},
  310.   {plyrrt1_bits, plyrrt1m_bits, plyrrt1_width, plyrrt1_height, {CELL_WIDTH, CELL_HEIGHT}},
  311.   {plyrrt2_bits, plyrrt2m_bits, plyrrt2_width, plyrrt2_height, {CELL_WIDTH, CELL_HEIGHT}},
  312.   {plyrup1_bits, plyrup1m_bits, plyrup1_width, plyrup1_height, {CELL_WIDTH, CELL_HEIGHT}},
  313.   {plyrup2_bits, plyrup2m_bits, plyrup2_width, plyrup2_height, {CELL_WIDTH, CELL_HEIGHT}},
  314.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 0, 2},
  315.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 1, 2},
  316.   /*}}}*/
  317.   /*{{{  4:player push (l, r)*/
  318.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER_PUSH + 2, 1},
  319.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER_PUSH + 3, 1},
  320.   {plyrps1_bits, plyrps1m_bits, plyrps1_width, plyrps1_height, {CELL_WIDTH, CELL_HEIGHT}},
  321.   {plyrps2_bits, plyrps2m_bits, plyrps2_width, plyrps2_height, {CELL_WIDTH, CELL_HEIGHT}},
  322.   /*}}}*/
  323.   /*{{{  2:player dead (l, r)*/
  324.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 4, 2},
  325.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_PLAYER + 6, 2},
  326.   /*}}}*/
  327.   /*{{{  10:squished*/
  328.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_SQUISHED + 1, 1},
  329.   {normsq_bits, normsqm_bits, normsq_width, normsq_height, {CELL_WIDTH, CELL_HEIGHT / 4}},
  330.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_SQUISHED + 3, 1},
  331.   {mnchsq_bits, mnchsqm_bits, mnchsq_width, mnchsq_height, {CELL_WIDTH, CELL_HEIGHT / 4}},
  332.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_SQUISHED + 5, 0},
  333.   {xtrasq_bits, xtrasqm_bits, xtrasq_width, xtrasq_height, {CELL_WIDTH, CELL_HEIGHT / 4}},
  334.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_SQUISHED + 7, 1},
  335.   {dronsq_bits, dronsqm_bits, dronsq_width, dronsq_height, {CELL_WIDTH, CELL_HEIGHT / 4}},
  336.   {NULL, NULL, 0, 0, {0, 0}, SPRITE_SQUISHED + 9, 1},
  337.   {plyrsq_bits, plyrsqm_bits, plyrsq_width, plyrsq_height, {CELL_WIDTH, CELL_HEIGHT / 4}},
  338.   /*}}}*/
  339.   /*{{{  2:chomp (open, closed)*/
  340.   {chmpopn_bits, chmpopnm_bits, chmpopn_width, chmpopn_height, {CELL_WIDTH, CELL_HEIGHT}},
  341.   {chmpcls_bits, chmpclsm_bits, chmpcls_width, chmpcls_height, {CELL_WIDTH, CELL_HEIGHT}},
  342.   /*}}}*/
  343.   /*{{{  8:m r i s*/
  344.   {solidm_bits, bigm_bits, solidm_width, solidm_height, {CELL_WIDTH, CELL_HEIGHT}},
  345.   {solidr_bits, bigr_bits, solidr_width, solidr_height, {CELL_WIDTH, CELL_HEIGHT}},
  346.   {solidi_bits, bigi_bits, solidi_width, solidi_height, {CELL_WIDTH, CELL_HEIGHT}},
  347.   {solids_bits, bigs_bits, solids_width, solids_height, {CELL_WIDTH, CELL_HEIGHT}},
  348.   {shellm_bits, bigm_bits, shellm_width, shellm_height, {CELL_WIDTH, CELL_HEIGHT}},
  349.   {shellr_bits, bigr_bits, shellr_width, shellr_height, {CELL_WIDTH, CELL_HEIGHT}},
  350.   {shelli_bits, bigi_bits, shelli_width, shelli_height, {CELL_WIDTH, CELL_HEIGHT}},
  351.   {shells_bits, bigs_bits, shells_width, shells_height, {CELL_WIDTH, CELL_HEIGHT}},
  352.   /*}}}*/
  353.   /*{{{  5:prizes*/
  354.   {cake_bits,    cakem_bits,    cake_width,    cake_height,    {CELL_WIDTH, CELL_HEIGHT}},
  355.   {spanner_bits, spannerm_bits, spanner_width, spanner_height, {CELL_WIDTH, CELL_HEIGHT}},
  356.   {brolly_bits,  brollym_bits,  brolly_width,  brolly_height,  {CELL_WIDTH, CELL_HEIGHT}},
  357.   {mushrm_bits,  mushrmm_bits,  mushrm_width,  mushrm_height,  {CELL_WIDTH, CELL_HEIGHT}},
  358.   {clock_bits,   clockm_bits,   clock_width,   clock_height,   {CELL_WIDTH, CELL_HEIGHT}},
  359.   /*}}}*/
  360. };
  361. /*}}}*/
  362. /*{{{  static SPRITE spritet[2] =*/
  363. static SPRITE spritet[2] =
  364. {
  365.   {solidt_bits, bigt_bits, solidt_width, solidt_height, {CELL_WIDTH, CELL_HEIGHT}},
  366.   {shellt_bits, bigt_bits, shellt_width, shellt_height, {CELL_WIDTH, CELL_HEIGHT}},
  367. };
  368. /*}}}*/
  369. /*{{{  static SPRITE icons[2] =*/
  370. static SPRITE icons[2] =
  371. {
  372.   {NULL, mris_bits, mris_width, mris_height},
  373.   {NULL, msit_bits, msit_width, msit_height},
  374. };
  375. /*}}}*/
  376. /*{{{  APPLE_SIZE const apple_sizes[6] =*/
  377. APPLE_SIZE const apple_sizes[6] =
  378.   {
  379.     {{CELL_WIDTH, CELL_HEIGHT}, {0, 0}},
  380.     {{CELL_WIDTH, CELL_HEIGHT}, {0, 0}},
  381.     {{CELL_WIDTH, CELL_HEIGHT}, {0, 0}},
  382.     {{CELL_WIDTH, CELL_HEIGHT}, {0, 0}},
  383.     {{DECAY_WIDTH, DECAY_HEIGHT},
  384.       {(CELL_WIDTH - DECAY_WIDTH) / 2, CELL_HEIGHT - DECAY_HEIGHT}},
  385.     {{ROT_WIDTH, ROT_HEIGHT},
  386.       {(CELL_WIDTH - ROT_WIDTH) / 2, CELL_HEIGHT - ROT_HEIGHT}},
  387.   };
  388. /*}}}*/
  389. /*{{{  BOARD const boards[10] =*/
  390. #if BOARDS != 10
  391.   #error BOARDS != 10
  392. #endif
  393. /*
  394.  * the initial board maps are stored as character arrays
  395.  * X for a path
  396.  * @ for cherry
  397.  */
  398. BOARD const boards[BOARDS] =
  399.   {
  400.     /*{{{  board 0*/
  401.     {
  402.       0,
  403.       {
  404.     "..XXXXXXXX..",
  405.     ".XX......XX.",
  406.     "XXXX......XX",
  407.     "X..XX..@@@@X",
  408.     "X...XX.@@@@X",
  409.     "X@@@@X.....X",
  410.     "X@@@@X...@@X",
  411.     "X....XX..@@X",
  412.     "X@@@@.XX.@@X",
  413.     "X@@@@..XX@@X",
  414.     "XX..@@@@XXXX",
  415.     ".XX.@@@@.XX.",
  416.     "..XXXXXXXX..",
  417.       }
  418.     },
  419.     /*}}}*/
  420.     /*{{{  board 1*/
  421.     {
  422.       0,
  423.       {
  424.     "....XXXXXX..",
  425.     "@@...X...XX.",
  426.     "@@...X@@@@XX",
  427.     "@@.@@X@@@@.X",
  428.     "@@.@@X.....X",
  429.     "...@@X.....X",
  430.     "...@@X..@@.X",
  431.     ".....X..@@.X",
  432.     "@@@@.X..@@.X",
  433.     "@@@@.X..@@.X",
  434.     "XXX..X....XX",
  435.     "X.X..X...XX.",
  436.     "XXXXXXXXXX..",
  437.       }
  438.     },
  439.     /*}}}*/
  440.     /*{{{  board 2*/
  441.     {
  442.       1,
  443.       {
  444.     "..XXXXXXXX..",
  445.     ".XX......XX.",
  446.     "XX@@@@....XX",
  447.     "X.@@@@..@@.X",
  448.     "........@@.X",
  449.     "@@......@@.X",
  450.     "@@...X..@@XX",
  451.     "@@...XXXXXX.",
  452.     "@@.XXX....@@",
  453.     ".XXX@@@@..@@",
  454.     "XX..@@@@..@@",
  455.     "X.........@@",
  456.     "XXXXXXXXXXXX",
  457.       }
  458.     },
  459.     /*}}}*/
  460.     /*{{{  board 3*/
  461.     {
  462.       2,
  463.       {
  464.     "..XXXXXXXX..",
  465.     ".XX......XX.",
  466.     "XX........XX",
  467.     "X..@@@@.@@.X",
  468.     "@@.@@@@.@@.X",
  469.     "@@......@@.X",
  470.     "@@...X..@@XX",
  471.     "@@..XXXXXXX.",
  472.     "...@@.....XX",
  473.     "...@@..@@@@X",
  474.     "X..@@..@@@@X",
  475.     "XX.@@.....XX",
  476.     ".XXXXXXXXXX.",
  477.       }
  478.     },
  479.     /*}}}*/
  480.     /*{{{  board 4*/
  481.     {
  482.       2,
  483.       {
  484.     "....XXXXXX..",
  485.     "@@@@X....X..",
  486.     "@@@@X....X@@",
  487.     "...XX....X@@",
  488.     "@@.X...@@X@@",
  489.     "@@XX...@@X@@",
  490.     "@@X..X.@@X..",
  491.     "@@XXXX.@@X..",
  492.     "XXX......X..",
  493.     "X........X..",
  494.     "XXXXXXXXXXXX",
  495.     ".@@@@....X..",
  496.     ".@@@@XXXXX..",
  497.       }
  498.     },
  499.     /*}}}*/
  500.     /*{{{  board 5*/
  501.     {
  502.       2,
  503.       {
  504.     "XXXXXXXXXXXX",
  505.     "X...........",
  506.     "X.@@@@......",
  507.     "X.@@@@..@@@@",
  508.     "X.......@@@@",
  509.     "XXXXXXXXXXX.",
  510.     "....XXX...XX",
  511.     ".@@.XXX..@@X",
  512.     ".@@......@@X",
  513.     ".@@.@@@@.@@X",
  514.     "X@@.@@@@.@@X",
  515.     "XX........XX",
  516.     ".XXXXXXXXXX.",
  517.       }
  518.     },
  519.     /*}}}*/
  520.     /*{{{  board 6*/
  521.     {
  522.       2,
  523.       {
  524.     "..XXXXXXXXXX",
  525.     ".XX.........",
  526.     "XX..........",
  527.     "X.@@.@@@@.@@",
  528.     "X.@@.@@@@.@@",
  529.     "X.@@......@@",
  530.     "X.@@.X....@@",
  531.     "XXXXXXXXXXX.",
  532.     "X.........XX",
  533.     "X@@@@......X",
  534.     "X@@@@.@@@@.X",
  535.     "XX....@@@@XX",
  536.     ".XXXXXXXXXX.",
  537.       }
  538.     },
  539.     /*}}}*/
  540.     /*{{{  board 7*/
  541.     {
  542.       3,
  543.       {
  544.     "XXXXXXXXXXXX",
  545.     "X..........X",
  546.     ".@@.......XX",
  547.     ".@@.@@@@.XX.",
  548.     ".@@.@@@@XX..",
  549.     ".@@....XX.@@",
  550.     ".....XXX..@@",
  551.     ".....XX...@@",
  552.     "@@@@.X.@@.@@",
  553.     "@@@@.X.@@...",
  554.     ".....X.@@...",
  555.     ".....X.@@...",
  556.     ".....X......",
  557.       }
  558.     },
  559.     /*}}}*/
  560.     /*{{{  board 8*/
  561.     {
  562.       3,
  563.       {
  564.     "..XXXXXXXX..",
  565.     ".XX......XX.",
  566.     "XX@@.@@.@@XX",
  567.     "X.@@.@@.@@.X",
  568.     "X.@@.@@.@@.X",
  569.     "XX@@.@@.@@XX",
  570.     ".XX..X...XX.",
  571.     "..XXXXXXXX..",
  572.     "XXX......XXX",
  573.     "X@@@@......X",
  574.     "X@@@@.@@@@.X",
  575.     "XX....@@@@XX",
  576.     ".XXXXXXXXXX.",
  577.       }
  578.     },
  579.     /*}}}*/
  580.     /*{{{  board 9*/
  581.     {
  582.       3,
  583.       {
  584.     "..XXXXXXXX..",
  585.     ".XX......XX.",
  586.     "XX...@@@@.XX",
  587.     "X.@@.@@@@..X",
  588.     "X.@@.......X",
  589.     "X.@@...@@@@X",
  590.     "XX@@.X.@@@@X",
  591.     ".XXXXXXXXXXX",
  592.     "@@.........X",
  593.     "@@....@@@@.X",
  594.     "@@....@@@@XX",
  595.     "@@.......XX.",
  596.     "XXXXXXXXXX..",
  597.       }
  598.     },
  599.     /*}}}*/
  600.   };
  601. /*}}}*/
  602. char keystrokes[5] = {'\'', '/', 'z', 'x', ' '};
  603. /*{{{  COORD const ball_hold[16] =*/
  604. /*{{{  held ball offsets*/
  605. #define PLAYER_RIGHT1_BALL_X   (plyrrt1_x_hot - CELL_WIDTH / 2)
  606. #define PLAYER_RIGHT1_BALL_Y   (plyrrt1_y_hot - CELL_HEIGHT / 2)
  607. #define PLAYER_UP1_BALL_X      (plyrup1_x_hot - CELL_WIDTH / 2)
  608. #define PLAYER_UP1_BALL_Y      (plyrup1_y_hot - CELL_HEIGHT / 2)
  609. #define PLAYER_RIGHT2_BALL_X   (plyrrt2_x_hot - CELL_WIDTH / 2)
  610. #define PLAYER_RIGHT2_BALL_Y   (plyrrt2_y_hot - CELL_HEIGHT / 2)
  611. #define PLAYER_UP2_BALL_X      (plyrup2_x_hot - CELL_WIDTH / 2)
  612. #define PLAYER_UP2_BALL_Y      (plyrup2_y_hot - CELL_HEIGHT / 2)
  613. #define PLAYER_PUSH1_BALL_X    (plyrps1_x_hot - CELL_WIDTH / 2)
  614. #define PLAYER_PUSH1_BALL_Y    (plyrps1_y_hot - CELL_HEIGHT / 2)
  615. #define PLAYER_PUSH2_BALL_X    (plyrps2_x_hot - CELL_WIDTH / 2)
  616. #define PLAYER_PUSH2_BALL_Y    (plyrps2_y_hot - CELL_HEIGHT / 2)
  617. /*}}}*/
  618. COORD const ball_hold[16] =
  619. {
  620.  {-PLAYER_UP1_BALL_X - BALL_WIDTH / 2,  PLAYER_UP1_BALL_Y - BALL_HEIGHT / 2},
  621.  {-PLAYER_UP2_BALL_X - BALL_WIDTH / 2,  PLAYER_UP2_BALL_Y - BALL_HEIGHT / 2},
  622.  { PLAYER_UP1_BALL_X - BALL_WIDTH / 2, -PLAYER_UP1_BALL_Y - BALL_HEIGHT / 2},
  623.  { PLAYER_UP2_BALL_X - BALL_WIDTH / 2, -PLAYER_UP2_BALL_Y - BALL_HEIGHT / 2},
  624.  {-PLAYER_RIGHT1_BALL_X - BALL_WIDTH / 2, PLAYER_RIGHT1_BALL_Y - BALL_HEIGHT / 2},
  625.  {-PLAYER_RIGHT2_BALL_X - BALL_WIDTH / 2, PLAYER_RIGHT2_BALL_Y - BALL_HEIGHT / 2},
  626.  { PLAYER_RIGHT1_BALL_X - BALL_WIDTH / 2, PLAYER_RIGHT1_BALL_Y - BALL_HEIGHT / 2},
  627.  { PLAYER_RIGHT2_BALL_X - BALL_WIDTH / 2, PLAYER_RIGHT2_BALL_Y - BALL_HEIGHT / 2},
  628.  { PLAYER_UP1_BALL_X - BALL_WIDTH / 2,  PLAYER_UP1_BALL_Y - BALL_HEIGHT / 2},
  629.  { PLAYER_UP2_BALL_X - BALL_WIDTH / 2,  PLAYER_UP2_BALL_Y - BALL_HEIGHT / 2},
  630.  {-PLAYER_UP1_BALL_X - BALL_WIDTH / 2, -PLAYER_UP1_BALL_Y - BALL_HEIGHT / 2},
  631.  {-PLAYER_UP2_BALL_X - BALL_WIDTH / 2, -PLAYER_UP2_BALL_Y - BALL_HEIGHT / 2},
  632.  {-PLAYER_PUSH1_BALL_X - BALL_WIDTH / 2, PLAYER_PUSH1_BALL_Y - BALL_HEIGHT / 2},
  633.  {-PLAYER_PUSH2_BALL_X - BALL_WIDTH / 2, PLAYER_PUSH2_BALL_Y - BALL_HEIGHT / 2},
  634.  { PLAYER_PUSH1_BALL_X - BALL_WIDTH / 2, PLAYER_PUSH1_BALL_Y - BALL_HEIGHT / 2},
  635.  { PLAYER_PUSH2_BALL_X - BALL_WIDTH / 2, PLAYER_PUSH2_BALL_Y - BALL_HEIGHT / 2},
  636. };
  637. /*}}}*/
  638. /*{{{  COORD const ball_throw[8] =*/
  639. COORD const ball_throw[8] =
  640. {
  641.   {-GAP_WIDTH / 2, -(CELL_HEIGHT + GAP_HEIGHT) / 2},
  642.   {GAP_WIDTH / 2, (CELL_HEIGHT + GAP_HEIGHT) / 2},
  643.   {-(CELL_WIDTH + GAP_WIDTH) / 2, GAP_HEIGHT / 2},
  644.   {(CELL_WIDTH + GAP_WIDTH) / 2, GAP_HEIGHT / 2},
  645.   {GAP_WIDTH / 2, -(CELL_HEIGHT + GAP_HEIGHT) / 2},
  646.   {-GAP_WIDTH / 2, (CELL_HEIGHT + GAP_HEIGHT) / 2},
  647.   {-(CELL_WIDTH + GAP_WIDTH) / 2, GAP_HEIGHT / 2},
  648.   {(CELL_WIDTH + GAP_WIDTH) / 2, GAP_HEIGHT / 2},
  649. };
  650. /*}}}*/
  651. int const ball_dir[8] = {0, 1, 2, 1, 3, 2, 2, 1};
  652. /*{{{  int const player_dies[8] =*/
  653. int const player_dies[8] =
  654.   {
  655.     SPRITE_PLAYER_DEAD + 1,
  656.     SPRITE_PLAYER + 0,
  657.     SPRITE_PLAYER + 4,
  658.     SPRITE_PLAYER + 2,
  659.     SPRITE_PLAYER + 8,
  660.     SPRITE_PLAYER + 6,
  661.     SPRITE_PLAYER + 10,
  662.     SPRITE_PLAYER_DEAD + 0,
  663.   };
  664. /*}}}*/
  665. /*{{{  char const *title_text[] =*/
  666. char const *title_text[] =
  667.   {
  668.     "(C) 1992 Nathan Sidwell",
  669. #if __STDC__
  670.     XMRISVERSION " " __DATE__, "",
  671. #else
  672.     "                           ", /* should be enough space */
  673. #endif
  674.     "Z - Left", "X - Right", "' - Up", "/ - Down", "Space - Throw",
  675.     "Or use the mouse", "P - Pause", "Q - Quit",
  676.     "Press a key or button to start", NULL
  677.   };
  678. /*}}}*/
  679. #if SQUISH_SCORES != 7
  680.   #error SQUISH_SCORES != 7
  681. #endif
  682. int const squish_scores[SQUISH_SCORES] = {0, 1000, 2000, 4000, 6000, 8000, 9900};
  683. /*}}}*/
  684. /*{{{  void create_resources(arc, argv)*/
  685. extern void create_resources FUNCARGLIST((argc, argv))
  686. int     argc    FUNCARGSEP
  687. char    **argv  FUNCARGTERM
  688. {
  689.   display.display = XOpenDisplay(display.name);
  690.   /*{{{  opened?*/
  691.   if(!display.display)
  692.     fatal_error("Cannot open display \"%s\"",
  693.     display.name ? display.name : "DEFAULT", stderr);
  694.   /*}}}*/
  695.   /*{{{  open the display*/
  696.   {
  697.     display.screen = DefaultScreen(display.display);
  698.     display.colormap = DefaultColormap(display.display, display.screen);
  699.     display.root = DefaultRootWindow(display.display);
  700.     display.depth = DefaultDepth(display.display, display.screen);
  701.     display.black = BlackPixel(display.display, display.screen);
  702.     display.white = WhitePixel(display.display, display.screen);
  703.     display.xor = display.black ^ display.white; /* for xor context */
  704.     /*
  705.      * We want to suspend the game in case the window is iconified.
  706.      * This is more difficult than it sounds.  On the Sun, iconification
  707.      * seems to produce an UnmapNotify event -- very nice.  DECwindows,
  708.      * however, informs the application by generating a PropertyNotify
  709.      * event on a DEC-specific property -- very nasty.  The atom is
  710.      * not defined in any of the DECwindows headers, so we will try
  711.      * to get its value from the server, and use it later.  We are
  712.      * hoping here that all non-DECwindows servers will return None
  713.      * for this atom.
  714.      */
  715.     display.DEC_icon_atom =
  716.     XInternAtom(display.display, "DEC_WM_ICON_STATE", True);
  717.     display.event_mask = ExposureMask | (display.DEC_icon_atom == None ?
  718.     StructureNotifyMask : PropertyChangeMask);
  719.   }
  720.   /*}}}*/
  721.   /*{{{  reverse video?*/
  722.   if(flags.reverse)
  723.     {
  724.       unsigned long temp;
  725.     
  726.       temp = display.black;
  727.       display.black = display.white;
  728.       display.white = temp;
  729.     }
  730.   /*}}}*/
  731.   /*{{{  set foreground & background types*/
  732.   {
  733.     display.background = display.white == 0 ? COLOUR_ZERO :
  734.     display.white == (1 << display.depth) - 1 ? COLOUR_ONE :
  735.     COLOUR_WEIRD;
  736.     display.foreground = display.black == 0 ? COLOUR_ZERO :
  737.     display.black == (1 << display.depth) - 1 ? COLOUR_ONE :
  738.     COLOUR_WEIRD;
  739.   }
  740.   /*}}}*/
  741.   /*{{{  get a font*/
  742.   {
  743.     font.font = XLoadFont(display.display, font.name);
  744.     if(!font.font)
  745.       fatal_error("Cannot load font \"%s\"", font.name);
  746.   }
  747.   /*}}}*/
  748.   /*{{{  create graphics contexts*/
  749.   {
  750.     XGCValues gcv;
  751.     CONTEXT   *cptr;
  752.     unsigned  count;
  753.     
  754.     gcv.plane_mask = AllPlanes;
  755.     gcv.font       = font.font;
  756.     gcv.graphics_exposures = False;
  757.     gcv.line_width = 1;
  758.     gcv.line_style = LineSolid;
  759.     gcv.join_style = JoinMiter;
  760.     gcv.fill_style = FillSolid;
  761.     for(cptr = gcsdefine, count = 0; count != GCS; count++, cptr++)
  762.       {
  763.     gcv.function = cptr->function;
  764.     gcv.foreground = *cptr->fgp;
  765.     gcv.background = *cptr->bgp;
  766.     GCN(count) = XCreateGC(display.display, display.root, 
  767.         GCForeground | GCBackground | GCFunction |
  768.         GCFont | GCGraphicsExposures | GCPlaneMask |
  769.         GCLineStyle | GCLineWidth | GCJoinStyle | GCFillStyle, &gcv);
  770.     if(!GCN(count))
  771.       fatal_error("Cannot create context %d", count);
  772.       }
  773.   }
  774.   /*}}}*/
  775.   /*{{{  create window*/
  776.   {
  777.     XSizeHints hints;
  778.     XColor colors[2];
  779.     Pixmap cursor, mask;
  780.     
  781.     hints.flags = PSize | PMinSize | PMaxSize;
  782.     hints.width = WINDOW_WIDTH;
  783.     hints.height = WINDOW_HEIGHT;
  784.     hints.min_width = hints.max_width = hints.width;
  785.     hints.min_height = hints.max_height = hints.height;
  786.     colors[0].pixel = display.black;
  787.     colors[1].pixel = display.white;
  788.     XQueryColors(display.display, display.colormap, colors, 2);
  789.     display.icon = XCreatePixmapFromBitmapData(display.display,
  790.     display.root, icons[flags.gender].mask_bits,
  791.     icons[flags.gender].width, icons[flags.gender].height, 1, 0, 1);
  792.     if(!display.icon)
  793.       fatal_error("Cannot create window icon");
  794.     cursor = mask = 0;
  795.     cursor = XCreatePixmapFromBitmapData(display.display,
  796.     display.root, cursor_bits,
  797.     cursor_width, cursor_height, 1, 0, 1);
  798.     mask = XCreatePixmapFromBitmapData(display.display,
  799.     display.root, cursorm_bits,
  800.     cursorm_width, cursorm_height, 1, 0, 1);
  801.     if(cursor && mask)
  802.       display.cursor = XCreatePixmapCursor(display.display,
  803.       cursor, mask, &colors[0], &colors[1],
  804.       cursor_x_hot, cursor_y_hot);
  805.     if(cursor)
  806.       XFreePixmap(display.display, cursor);
  807.     if(mask)
  808.       XFreePixmap(display.display, mask);
  809.     if(!display.cursor)
  810.       fatal_error("Cannot create cursor icon");
  811.     display.window = XCreateSimpleWindow(display.display, display.root,
  812.     0, 0, hints.width, hints.height, 1, display.black, display.white);
  813.     if(!display.window)
  814.       fatal_error("Cannot create window");
  815.     XSetStandardProperties(display.display, display.window,
  816.     game_name, game_name, display.icon, argv, argc, &hints);
  817.     XDefineCursor(display.display, display.window, display.cursor);
  818.   }
  819.   /*}}}*/
  820.   display.back = XCreatePixmap(display.display, display.root,
  821.       WINDOW_WIDTH, WINDOW_HEIGHT, display.depth);
  822.   display.copy = XCreatePixmap(display.display, display.root,
  823.       WINDOW_WIDTH, WINDOW_HEIGHT, display.depth);
  824.   if(!display.back || !display.copy)
  825.     fatal_error("Cannot create window copies");
  826.   /*{{{  are we she?*/
  827.   if(flags.gender)
  828.     {
  829.       memcpy(&sprites[SPRITE_MRIS + 1], &sprites[SPRITE_MRIS + 3],
  830.       sizeof(SPRITE));
  831.       memcpy(&sprites[SPRITE_MRIS + 5], &sprites[SPRITE_MRIS + 7],
  832.       sizeof(SPRITE));
  833.       memcpy(&sprites[SPRITE_MRIS + 3],  &spritet[0], sizeof(SPRITE));
  834.       memcpy(&sprites[SPRITE_MRIS + 7],  &spritet[1], sizeof(SPRITE));
  835.     }
  836.   /*}}}*/
  837.   /*{{{  create sprites*/
  838.   {
  839.     unsigned  i;
  840.     SPRITE    *sptr;
  841.     
  842.     /*{{{  generate all the ones from bitmaps*/
  843.     for(i = 0, sptr = sprites; i != SPRITES; i++, sptr++)
  844.       {
  845.     /* check that its the size we expected */
  846.     assert((!sptr->expected.x || sptr->expected.x == sptr->width) &&
  847.         (!sptr->expected.y || sptr->expected.y == sptr->height));
  848.     if(sptr->mask_bits || sptr->image_bits)
  849.       {
  850.         assert(sptr->width && sptr->height);
  851.         if(sptr->image_bits)
  852.           sptr->image = XCreatePixmapFromBitmapData(display.display,
  853.           display.root, sptr->image_bits,
  854.           sptr->width, sptr->height,
  855.           display.black, display.white, display.depth);
  856.         else
  857.           {
  858.         sptr->image = XCreatePixmap(display.display, display.root,
  859.             sptr->width, sptr->height, display.depth);
  860.         if(sptr->image)
  861.           XFillRectangle(display.display, sptr->image, GCN(GC_CLEAR),
  862.               0, 0, sptr->width, sptr->height);
  863.           }
  864.         if(sptr->mask_bits && sptr->image)
  865.           {
  866.         sptr->mask = XCreatePixmapFromBitmapData(display.display,
  867.             display.root, sptr->mask_bits, sptr->width, sptr->height,
  868.             ((unsigned long)1 << display.depth) - (unsigned long)1,
  869.             (unsigned long)0, display.depth);
  870.         if(sptr->mask)
  871.           XCopyArea(display.display, sptr->mask, sptr->image, GCN(GC_AND),
  872.               0, 0, sptr->width, sptr->height, 0, 0);
  873.           }
  874.         if((!sptr->mask && sptr->mask_bits) || !sptr->image)
  875.           fatal_error("Cannot create sprite %d", i);
  876.       }
  877.       }
  878.     /*}}}*/
  879.     /*{{{  do the ball*/
  880.     {
  881.       sptr = &sprites[SPRITE_BALL];
  882.       ball_xor = XCreatePixmap(display.display, display.window,
  883.       BALL_WIDTH, BALL_HEIGHT, display.depth);
  884.       if(!ball_xor)
  885.     fatal_error("Cannot create ball sprite");
  886.       XFillRectangle(display.display, ball_xor, GCN(GC_MASK),
  887.       0, 0, BALL_WIDTH, BALL_HEIGHT);
  888.       XFillRectangle(display.display, ball_xor, GCN(GC_BALL),
  889.       0, 0, BALL_WIDTH, BALL_HEIGHT);
  890.       XCopyArea(display.display, sptr->mask, ball_xor, GCN(GC_AND),
  891.       0, 0, BALL_WIDTH, BALL_HEIGHT, 0, 0);
  892.     }
  893.     /*}}}*/
  894.     /*{{{  now do the copies*/
  895.     for(sptr = sprites, i = SPRITES; i--; sptr++)
  896.       if(!sptr->copy)
  897.     {
  898.       /* Sun's assert macro is broken, so I have to
  899.        * put it in a scope */
  900.       assert(sptr->mask_bits || sptr->image_bits);
  901.     }
  902.       else
  903.     {
  904.       SPRITE    *optr;
  905.           
  906.       optr = &sprites[sptr->copy];
  907.       assert(optr->width && optr->height);
  908.       sptr->width = optr->width;
  909.       sptr->height = optr->height;
  910.       switch(sptr->reflect)
  911.       {
  912.         /*{{{  case 0: (no reflections)*/
  913.         case 0:
  914.           sptr->mask = optr->mask;
  915.           sptr->image = optr->image;
  916.           break;
  917.         /*}}}*/
  918.         /*{{{  case 1: (vertical axis)*/
  919.         case 1:
  920.         {
  921.           int       i;
  922.                           
  923.           sptr->mask = XCreatePixmap(display.display, display.root,
  924.           sptr->width, sptr->height, display.depth);
  925.           sptr->image = XCreatePixmap(display.display, display.root,
  926.           sptr->width, sptr->height, display.depth);
  927.           if(sptr->image && sptr->mask)
  928.         for(i = sptr->width; i--;)
  929.           {
  930.             XCopyArea(display.display, optr->mask, sptr->mask,
  931.             GCN(GC_COPY),
  932.             i, 0, 1, sptr->height, sptr->width - i - 1, 0);
  933.             XCopyArea(display.display, optr->image, sptr->image,
  934.             GCN(GC_COPY),
  935.             i, 0, 1, sptr->height, sptr->width - i - 1, 0);
  936.           }
  937.           break;
  938.         }
  939.         /*}}}*/
  940.         /*{{{  case 2: (horizontal axis)*/
  941.         case 2:
  942.         {
  943.           int       i;
  944.                           
  945.           sptr->mask = XCreatePixmap(display.display, display.root,
  946.           sptr->width, sptr->height, display.depth);
  947.           sptr->image = XCreatePixmap(display.display, display.root,
  948.           sptr->width, sptr->height, display.depth);
  949.           if(sptr->mask && sptr->image)
  950.         for(i = sptr->width; i--;)
  951.           {
  952.             XCopyArea(display.display, optr->mask, sptr->mask,
  953.             GCN(GC_COPY),
  954.             0, i, sptr->width, 1, 0, sptr->height - i - 1);
  955.             XCopyArea(display.display, optr->image, sptr->image,
  956.             GCN(GC_COPY),
  957.             0, i, sptr->width, 1, 0, sptr->height - i - 1);
  958.           }
  959.           break;
  960.         }
  961.         /*}}}*/
  962.         /*{{{  default*/
  963.         default:
  964.           assert(0);
  965.         /*}}}*/
  966.       }
  967.       if(!sptr->image || !sptr->mask)
  968.         fatal_error("Cannot generate sprite %d", SPRITES - 1 - i);
  969.     }
  970.     /*}}}*/
  971.   }
  972.   /*}}}*/
  973.   /*{{{  check ball hold is ok*/
  974.   {
  975.     unsigned  i;
  976.     
  977.     for(i = sizeof(ball_hold) / sizeof(COORD); i--;)
  978.       assert(ball_hold[i].x + CELL_WIDTH / 2 >= 0 &&
  979.       ball_hold[i].x + CELL_WIDTH / 2 <= CELL_WIDTH - BALL_WIDTH / 2 && 
  980.       ball_hold[i].y + CELL_HEIGHT / 2 >= 0 &&
  981.       ball_hold[i].y + CELL_HEIGHT / 2 <= CELL_HEIGHT - BALL_HEIGHT / 2);
  982.   }
  983.   /*}}}*/
  984.   /*{{{  create score pixmaps*/
  985.   {
  986.     unsigned  i;
  987.     
  988.     for(i = BOARD_SCORES; i--;)
  989.       {
  990.     update.score.list[i].image = XCreatePixmap(display.display,
  991.         display.root, DIGIT_WIDTH * 4, DIGIT_HEIGHT, display.depth);
  992.     update.score.list[i].mask = XCreatePixmap(display.display,
  993.         display.root, DIGIT_WIDTH * 4, DIGIT_HEIGHT, display.depth);
  994.     if(!update.score.list[i].image || !update.score.list[i].mask)
  995.       fatal_error("Cannot create score pixmap");
  996.       }
  997.   }
  998.   /*}}}*/
  999.   return;
  1000. }
  1001. /*}}}*/
  1002. /*{{{  void create_xtra_monster(index)*/
  1003. extern void create_xtra_monster FUNCARGLIST((index))
  1004. int   index FUNCARGTERM
  1005. {
  1006.   SPRITE    *dptr;
  1007.   SPRITE    *sptr;
  1008.   SPRITE    *lptr;
  1009.   unsigned  i;
  1010.   
  1011.   sptr = &sprites[SPRITE_XTRA];
  1012.   lptr = &sprites[SPRITE_EXTRA];
  1013.   for(dptr = &sprites[SPRITE_XTRA], sptr = &sprites[SPRITE_XTRA_SOURCE],
  1014.       i = MONSTER_IMAGES; i--; dptr++, sptr++)
  1015.     {
  1016.       XCopyArea(display.display, sptr->image, dptr->image, GCN(GC_COPY),
  1017.       0, 0, CELL_WIDTH, CELL_HEIGHT, 0, 0);
  1018.       XCopyArea(display.display, lptr->mask, dptr->image, GCN(GC_MASK),
  1019.       index * (CELL_WIDTH / 2), 0, CELL_WIDTH / 2, CELL_HEIGHT / 2,
  1020.       XTRA_LETTER_X, XTRA_LETTER_Y);
  1021.       XCopyArea(display.display, lptr[!(extra.got & 1 << index)].image,
  1022.       dptr->image, GCN(GC_OR),
  1023.       index * (CELL_WIDTH / 2), 0, CELL_WIDTH / 2, CELL_HEIGHT / 2,
  1024.       XTRA_LETTER_X, XTRA_LETTER_Y);
  1025.     }
  1026.   return;
  1027. }
  1028. /*}}}*/
  1029. /*{{{  void draw_extra_letter(index)*/
  1030. extern void draw_extra_letter FUNCARGLIST((index))
  1031. int     index  FUNCARGTERM
  1032. {
  1033.   SPRITE    *lptr;
  1034.   int       x;
  1035.   
  1036.   lptr = &sprites[SPRITE_EXTRA];
  1037.   x = XTRA_X + index * XTRA_SPACING;
  1038.   XFillRectangle(display.display, display.back, GCN(GC_CLEAR),
  1039.       x, XTRA_Y, CELL_WIDTH, CELL_HEIGHT);
  1040.   XCopyArea(display.display, lptr->mask,
  1041.       display.back, GCN(GC_MASK), index * (CELL_WIDTH / 2), 0,
  1042.       CELL_WIDTH / 2, CELL_HEIGHT / 2,
  1043.       x + XTRA_LETTER_X, XTRA_Y + XTRA_LETTER_Y);
  1044.   XCopyArea(display.display, lptr[!(extra.got & 1 << index)].image,
  1045.       display.back, GCN(GC_OR), index * (CELL_WIDTH / 2), 0,
  1046.       CELL_WIDTH / 2, CELL_HEIGHT / 2,
  1047.       x + XTRA_LETTER_X, XTRA_Y + XTRA_LETTER_Y);
  1048.   add_background(x, XTRA_Y, CELL_WIDTH, CELL_HEIGHT);
  1049.   return;
  1050. }
  1051. /*}}}*/
  1052. /*{{{  void release_resources()*/
  1053. extern void release_resources FUNCARGVOID
  1054. /*
  1055.  * frees all the resources we have allocated by create_resources
  1056.  */
  1057. {
  1058.   unsigned  i;
  1059.   SPRITE    *sptr;
  1060.  
  1061.   if(display.window)
  1062.     {
  1063.       XUnmapWindow(display.display, display.window);
  1064.       XUndefineCursor(display.display, display.window);
  1065.       XDestroyWindow(display.display, display.window);
  1066.     }
  1067.   if(font.font)
  1068.     XUnloadFont(display.display, font.font);
  1069.   if(display.cursor)
  1070.     XFreeCursor(display.display, display.cursor);
  1071.   if(display.copy)
  1072.     XFreePixmap(display.display, display.copy);
  1073.   if(display.back)
  1074.     XFreePixmap(display.display, display.back);
  1075.   if(display.icon)
  1076.     XFreePixmap(display.display, display.icon);
  1077.   /*{{{  free gcs*/
  1078.   {
  1079.     GC        *gcptr;
  1080.     unsigned  count;
  1081.     
  1082.     for(gcptr = gcs, count = GCS; count--; gcptr++)
  1083.       if(*gcptr)
  1084.     {
  1085.       XFreeGC(display.display, *gcptr);
  1086.       *gcptr = 0;
  1087.     }
  1088.   }
  1089.   /*}}}*/
  1090.   for(i = SPRITES, sptr = sprites; i--; sptr++)
  1091.     {
  1092.       if(!sptr->copy || sptr->reflect)
  1093.     {
  1094.       if(sptr->image)
  1095.         XFreePixmap(display.display, sptr->image);
  1096.       if(sptr->mask)
  1097.         XFreePixmap(display.display, sptr->mask);
  1098.     }
  1099.     }
  1100.   for(i = BOARD_SCORES; i--;)
  1101.     {
  1102.       if(update.score.list[i].image)
  1103.     XFreePixmap(display.display, update.score.list[i].image);
  1104.       if(update.score.list[i].mask)
  1105.     XFreePixmap(display.display, update.score.list[i].mask);
  1106.     }
  1107.   if(display.display)
  1108.     {
  1109.       XFlush(display.display);
  1110.       XCloseDisplay(display.display);
  1111.     }
  1112.   return;
  1113. }
  1114. /*}}}*/
  1115.